
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <stdio.h>

int main(int argc, char **argv) {
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <input_file>\n", argv[0]);
        return 1;
    }

    AVFormatContext *fmt_ctx = NULL;
    AVCodecContext *video_dec_ctx = NULL, *audio_dec_ctx = NULL;
    const AVCodec *video_codec = NULL, *audio_codec = NULL;
    int video_stream_idx = -1, audio_stream_idx = -1;
    AVFrame *frame = av_frame_alloc();
    AVPacket *pkt = av_packet_alloc();

    // 1. 打开输入文件
    if (avformat_open_input(&fmt_ctx, argv[1], NULL, NULL) < 0) {
        fprintf(stderr, "Could not open input file\n");
        goto cleanup;
    }

    // 2. 获取流信息
    if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
        fprintf(stderr, "Failed to get stream info\n");
        goto cleanup;
    }

    // 3. 查找视频/音频流
    for (int i = 0; i < fmt_ctx->nb_streams; i++) {
        AVStream *stream = fmt_ctx->streams[i];
        if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && video_stream_idx < 0) {
            video_stream_idx = i;
            video_codec = avcodec_find_decoder(stream->codecpar->codec_id);
        } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_stream_idx < 0) {
            audio_stream_idx = i;
            audio_codec = avcodec_find_decoder(stream->codecpar->codec_id);
        }
    }

    // 4. 初始化解码器
    if (video_codec) {
        video_dec_ctx = avcodec_alloc_context3(video_codec);
        avcodec_parameters_to_context(video_dec_ctx, fmt_ctx->streams[video_stream_idx]->codecpar);
        if (avcodec_open2(video_dec_ctx, video_codec, NULL) < 0) {
            fprintf(stderr, "Failed to open video codec\n");
            goto cleanup;
        }
    }

    if (audio_codec) {
        audio_dec_ctx = avcodec_alloc_context3(audio_codec);
        avcodec_parameters_to_context(audio_dec_ctx, fmt_ctx->streams[audio_stream_idx]->codecpar);
        if (avcodec_open2(audio_dec_ctx, audio_codec, NULL) < 0) {
            fprintf(stderr, "Failed to open audio codec\n");
            goto cleanup;
        }
    }

    // 5. 解码循环
    while (av_read_frame(fmt_ctx, pkt) >= 0) {
        AVCodecContext *dec_ctx = NULL;
        if (pkt->stream_index == video_stream_idx) {
            dec_ctx = video_dec_ctx;
            printf("Video packet: pts=%ld, size=%d\n", pkt->pts, pkt->size);
        } else if (pkt->stream_index == audio_stream_idx) {
            dec_ctx = audio_dec_ctx;
            printf("Audio packet: pts=%ld, size=%d\n", pkt->pts, pkt->size);
        }

        if (dec_ctx) {
            // 发送数据包到解码器
            if (avcodec_send_packet(dec_ctx, pkt) < 0) {
                fprintf(stderr, "Error sending packet to decoder\n");
                continue;
            }

            // 接收解码后的帧
            while (avcodec_receive_frame(dec_ctx, frame) >= 0) {
                if (pkt->stream_index == video_stream_idx) {
                    printf("Decoded video frame: %dx%d, format=%d\n", 
                           frame->width, frame->height, frame->format);
                } else {
                    printf("Decoded audio frame: %d samples, format=%d\n",
                           frame->nb_samples, frame->format);
                }
            }
        }
        av_packet_unref(pkt);
    }

cleanup:
    av_packet_free(&pkt);
    av_frame_free(&frame);
    avcodec_free_context(&video_dec_ctx);
    avcodec_free_context(&audio_dec_ctx);
    avformat_close_input(&fmt_ctx);
    return 0;
}
